package com.xwtech.framework.pub.filter;

import java.io.IOException;
import java.util.Iterator;
import java.util.HashMap;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.regexp.RE;
import org.springframework.web.filter.OncePerRequestFilter;

import com.xwtech.framework.pub.po.FrameUrl;
import com.xwtech.framework.login.pub.AbstractLoginToken;
import com.xwtech.framework.pub.web.SessionNameConstants;
import com.xwtech.framework.pub.result.ResultInfo;
import com.xwtech.framework.pub.result.ResultInfos;
import com.xwtech.framework.pub.result.ResultConstants;
import com.xwtech.framework.pub.web.RequestNameConstants;
import com.xwtech.framework.pub.web.FrameworkApplication;

/**
 * 
 * <p>
 * Title: Framework
 * </p>
 * <p>
 * Description:Framework
 * </p>
 * <p>
 * Copyright: Copyright (c) 2005
 * </p>
 * <p>
 * Company: xwtech.com
 * </p>
 * 
 * @author starxu
 * @version 1.0
 * 
 * 过滤url,ip,判断是否有权限能够被访问
 */
public class LoginTokenFilter extends OncePerRequestFilter {
	protected static final Logger logger = Logger
			.getLogger(LoginTokenFilter.class);

	private String loginPageUrl;

	public void setLoginPageUrl(String loginPageUrl) {
		this.loginPageUrl = loginPageUrl;
	}

	protected void doFilterInternal(HttpServletRequest request,
			HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		response.setBufferSize(8192);
		String currentURI = request.getRequestURI();
		String compareUrl = currentURI.substring(
				currentURI.lastIndexOf("/") + 1, currentURI.length());
		String frontUrl = currentURI.substring(0, currentURI.lastIndexOf("/"));
		AbstractLoginToken loginToken = (AbstractLoginToken) (request
				.getSession().getAttribute(SessionNameConstants.LOGIN_TOKEN));
		if (loginToken == null) // 登录令牌不存
		{
			if (currentURI != null
					&& currentURI.equals("/cring/jsp/user/login.do")) {
				String loginName = request.getParameter("loginName");
				String loginPwd = request.getParameter("loginPwd");
				if (loginName == null || loginPwd == null
						|| loginName.equals("") || loginName.equals("")
						|| loginPwd.equals("")) {
					HashMap map = new HashMap();
					ResultInfos resultInfos = new ResultInfos();
					resultInfos.setGotoUrl(this.loginPageUrl);
					resultInfos.add(new ResultInfo(
							ResultConstants.NOT_LOGIN_NOT_ACCESS_ROLE, null));
					map.put(RequestNameConstants.RESULTINFOS, resultInfos);
					request.setAttribute(RequestNameConstants.INFORMATION, map);
					request.getRequestDispatcher("information.jsp").forward(
							request, response);
					return;
				}
			}
			boolean isNeedRedirectLoginPage = true; // 是否要跳转到登录页面
			if (FrameworkApplication.frameworkProperties != null
					&& FrameworkApplication.frameworkProperties
							.getNotFilterUrls() != null) {
				// 尚未登录系统
				if (FrameworkApplication.frameworkProperties.getNotFilterUrls()
						.contains(compareUrl)) {
					isNeedRedirectLoginPage = false;
				}
				// 如果在notFilterUrls 指定了路径，则也支持直接通过
				if (FrameworkApplication.frameworkProperties.getNotFilterUrls()
						.contains(frontUrl))
					isNeedRedirectLoginPage = false;
			}
			// 提供给试听页面在未登录情况下，登录和定购等操作一起进行时，

			// 方法speckFor的放过

			if (currentURI != null
					&& currentURI
							.equals("/cring/jsp/user/ringManagerController.do")) {
				String postMethodName = request.getParameter("method");
				if (postMethodName.equals("speckFor")) {
					isNeedRedirectLoginPage = false;
				}
			}
			// 跳转到登录页
			if (isNeedRedirectLoginPage == true) {
				HashMap map = new HashMap();
				ResultInfos resultInfos = new ResultInfos();
				resultInfos.setGotoUrl(this.loginPageUrl);
				resultInfos.add(new ResultInfo(
						ResultConstants.NOT_LOGIN_NOT_ACCESS_ROLE, null));
				map.put(RequestNameConstants.RESULTINFOS, resultInfos);
				request.setAttribute(RequestNameConstants.INFORMATION, map);
				request.getRequestDispatcher("information.jsp").forward(
						request, response);
				return;
			}
		} else // 登录令牌存在
		{
			if (currentURI != null
					&& currentURI.equals("/cring/jsp/user/login.do")) {
				String loginName = request.getParameter("loginName");
				String loginPwd = request.getParameter("loginPwd");
				if (loginName == null || loginPwd == null
						|| loginName.equals("") || loginName.equals("")
						|| loginPwd.equals("")) {
					HashMap map = new HashMap();
					ResultInfos resultInfos = new ResultInfos();
					resultInfos.setGotoUrl(this.loginPageUrl);
					resultInfos.add(new ResultInfo(
							ResultConstants.NOT_LOGIN_NOT_ACCESS_ROLE, null));
					map.put(RequestNameConstants.RESULTINFOS, resultInfos);
					request.setAttribute(RequestNameConstants.INFORMATION, map);
					request.getRequestDispatcher("information.jsp").forward(
							request, response);
					return;
				}
			}
			boolean isNeedRedirectNotRolePage = true;// 是否要跳转到没有权限的页

			/* add by fq 2009.8.19 begin */
			/**
			 * 此处变更只针对后台管理程序，所有以下处理只涉及"/jsp/admin/"下的url链接
			 * 或者更特殊的“/jsp/user/fileupload”：upload框体涉及的
			 * 
			 * 因为变更，所有超级管理员和没关联用户组的用户的frameRoles都为null，
			 * 为了他们不再跳转到“无权限”出错提示页面，特改造如下： 如有冲突，请通知修正
			 */
			// 超级管理员or没关联用户组的用户，先判断url来源
			if (loginToken.getFrameRoles() == null
					|| loginToken.getFrameRoles().length == 0) {
				// 判断该请求是否来自后台模块的请求
				if (request.getRequestURI().lastIndexOf("/jsp/admin/") > -1
						|| request.getRequestURI().lastIndexOf(
								"/jsp/user/fileupload") > -1) {
					logger.debug("URL-->" + request.getRequestURI()
							+ "<--是来自后台管理模块的请求！参照特殊情况处理");
					isNeedRedirectNotRolePage = false;
				}
			} else {
				/* add by fq 2009.8.19 end */

				// 判断登录令牌权限
				for (int i = 0; i < loginToken.getFrameRoles().length; i++) {
					Iterator it = loginToken.getFrameRoles()[i].getFrameUrls()
							.iterator();
					while (it.hasNext())// 过滤url权限
					{
						FrameUrl frameUrl = (FrameUrl) it.next();
						// 正则表达式判断权限

						/**
						 * add by fq for
						 * 如果菜单不是叶子菜单，则frameUrl.getUrlValue()返回的是null，这里需要加以判断
						 * 直接跳出权限判断
						 */
						if (frameUrl.getUrlValue() == null) {
							isNeedRedirectNotRolePage = false;
							break;
						}
						/** modify by fq in 2009.8.17 */

						RE regexp = new RE(frameUrl.getUrlValue());
						if (regexp.match(currentURI)
								|| FrameworkApplication.frameworkProperties
										.getNotFilterUrls()
										.contains(compareUrl)) {
							isNeedRedirectNotRolePage = false;
							break;
						}
					}
				}
			}
			if (isNeedRedirectNotRolePage == true) {
				HashMap map = new HashMap();
				ResultInfos resultInfos = new ResultInfos();
				resultInfos.add(new ResultInfo(ResultConstants.NOT_ACCESS_ROLE,
						null));
				map.put(RequestNameConstants.RESULTINFOS, resultInfos);
				request.setAttribute(RequestNameConstants.INFORMATION, map);
				request.getRequestDispatcher("information.jsp").forward(
						request, response);
				return;
			}
		}

		long processBeginTime = System.currentTimeMillis();
		filterChain.doFilter(request, response);
		long processEndTime = System.currentTimeMillis();
		logger.debug("Process Time: " + (processEndTime - processBeginTime)
				+ " millisecond");
	}

}
